2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCER_SLIDERHANDLER_JUCEHEADER__
27 #define __JUCER_SLIDERHANDLER_JUCEHEADER__
29 //==============================================================================
32 class SliderHandler
: public ComponentTypeHandler
35 //==============================================================================
37 : ComponentTypeHandler ("Slider", "Slider", typeid (Slider
), 150, 24)
39 registerColour (Slider::backgroundColourId
, "background", "bkgcol");
40 registerColour (Slider::thumbColourId
, "thumb", "thumbcol");
41 registerColour (Slider::trackColourId
, "track", "trackcol");
42 registerColour (Slider::rotarySliderFillColourId
, "rotary fill", "rotarysliderfill");
43 registerColour (Slider::rotarySliderOutlineColourId
, "rotary outln", "rotaryslideroutline");
44 registerColour (Slider::textBoxTextColourId
, "textbox text", "textboxtext");
45 registerColour (Slider::textBoxBackgroundColourId
, "textbox bkgd", "textboxbkgd");
46 registerColour (Slider::textBoxHighlightColourId
, "textbox highlt", "textboxhighlight");
47 registerColour (Slider::textBoxOutlineColourId
, "textbox outln", "textboxoutline");
50 //==============================================================================
51 Component
* createNewComponent (JucerDocument
*)
53 return new Slider ("new slider");
56 //==============================================================================
57 XmlElement
* createXmlFor (Component
* comp
, const ComponentLayout
* layout
)
59 XmlElement
* e
= ComponentTypeHandler::createXmlFor (comp
, layout
);
61 Slider
* const s
= dynamic_cast <Slider
*> (comp
);
62 e
->setAttribute ("min", s
->getMinimum());
63 e
->setAttribute ("max", s
->getMaximum());
64 e
->setAttribute ("int", s
->getInterval());
65 e
->setAttribute ("style", sliderStyleToString (s
->getSliderStyle()));
66 e
->setAttribute ("textBoxPos", textBoxPosToString (s
->getTextBoxPosition()));
67 e
->setAttribute ("textBoxEditable", s
->isTextBoxEditable());
68 e
->setAttribute ("textBoxWidth", s
->getTextBoxWidth());
69 e
->setAttribute ("textBoxHeight", s
->getTextBoxHeight());
70 e
->setAttribute ("skewFactor", s
->getSkewFactor());
75 bool restoreFromXml (const XmlElement
& xml
, Component
* comp
, const ComponentLayout
* layout
)
77 if (! ComponentTypeHandler::restoreFromXml (xml
, comp
, layout
))
80 Slider
* const s
= dynamic_cast <Slider
*> (comp
);
82 s
->setRange (xml
.getDoubleAttribute ("min", 0.0),
83 xml
.getDoubleAttribute ("max", 10.0),
84 xml
.getDoubleAttribute ("int", 0.0));
86 s
->setSliderStyle (sliderStringToStyle (xml
.getStringAttribute ("style", "LinearHorizontal")));
88 s
->setTextBoxStyle (stringToTextBoxPos (xml
.getStringAttribute ("textBoxPos", "TextBoxLeft")),
89 ! xml
.getBoolAttribute ("textBoxEditable", true),
90 xml
.getIntAttribute ("textBoxWidth", 80),
91 xml
.getIntAttribute ("textBoxHeight", 20));
93 s
->setSkewFactor (xml
.getDoubleAttribute ("skewFactor", 1.0));
98 //==============================================================================
99 const String
getCreationParameters (Component
* component
)
101 return quotedString (component
->getName());
104 void fillInCreationCode (GeneratedCode
& code
, Component
* component
, const String
& memberVariableName
)
106 ComponentTypeHandler::fillInCreationCode (code
, component
, memberVariableName
);
108 Slider
* const s
= dynamic_cast <Slider
*> (component
);
111 r
<< memberVariableName
<< "->setRange ("
112 << s
->getMinimum() << ", " << s
->getMaximum() << ", " << s
->getInterval()
114 << memberVariableName
<< "->setSliderStyle (Slider::"
115 << sliderStyleToString (s
->getSliderStyle()) << ");\n"
116 << memberVariableName
<< "->setTextBoxStyle (Slider::"
117 << textBoxPosToString (s
->getTextBoxPosition())
118 << ", " << boolToString (! s
->isTextBoxEditable())
119 << ", " << s
->getTextBoxWidth() << ", " << s
->getTextBoxHeight() << ");\n"
120 << getColourIntialisationCode (component
, memberVariableName
);
122 if (needsCallback (component
))
123 r
<< memberVariableName
<< "->addListener (this);\n";
125 if (s
->getSkewFactor() != 1.0)
126 r
<< memberVariableName
<< "->setSkewFactor (" << s
->getSkewFactor() << ");\n";
129 code
.constructorCode
+= r
;
132 void fillInGeneratedCode (Component
* component
, GeneratedCode
& code
)
134 ComponentTypeHandler::fillInGeneratedCode (component
, code
);
136 if (needsCallback (component
))
138 String
& callback
= code
.getCallbackCode ("public SliderListener",
140 "sliderValueChanged (Slider* sliderThatWasMoved)",
143 if (callback
.isNotEmpty())
146 const String
memberVariableName (code
.document
->getComponentLayout()->getComponentMemberVariableName (component
));
147 const String
userCodeComment ("UserSliderCode_" + memberVariableName
);
150 << "if (sliderThatWasMoved == " << memberVariableName
151 << ")\n{\n //[" << userCodeComment
<< "] -- add your slider handling code here..\n //[/" << userCodeComment
<< "]\n}\n";
155 //==============================================================================
156 void getEditableProperties (Component
* component
, JucerDocument
& document
, Array
<PropertyComponent
*>& properties
)
158 ComponentTypeHandler::getEditableProperties (component
, document
, properties
);
160 Slider
* s
= dynamic_cast <Slider
*> (component
);
163 properties
.add (new SliderRangeProperty (s
, document
, "minimum", 0));
164 properties
.add (new SliderRangeProperty (s
, document
, "maximum", 1));
165 properties
.add (new SliderRangeProperty (s
, document
, "interval", 2));
166 properties
.add (new SliderTypeProperty (s
, document
));
167 properties
.add (new SliderTextboxProperty (s
, document
));
168 properties
.add (new SliderTextboxEditableProperty (s
, document
));
169 properties
.add (new SliderTextboxSizeProperty (s
, document
, true));
170 properties
.add (new SliderTextboxSizeProperty (s
, document
, false));
171 properties
.add (new SliderSkewProperty (s
, document
));
173 addColourProperties (component
, document
, properties
);
176 static bool needsCallback (Component
* slider
)
178 return true; //xxx should be a property
182 //==============================================================================
183 class SliderTypeProperty
: public ComponentChoiceProperty
<Slider
>
186 SliderTypeProperty (Slider
* slider
, JucerDocument
& document
)
187 : ComponentChoiceProperty
<Slider
> ("type", slider
, document
)
189 choices
.add ("Linear Horizontal");
190 choices
.add ("Linear Vertical");
191 choices
.add ("Linear Bar");
192 choices
.add ("Rotary");
193 choices
.add ("Rotary HorizontalDrag");
194 choices
.add ("Rotary VerticalDrag");
195 choices
.add ("Inc/Dec Buttons");
196 choices
.add ("Two Value Horizontal");
197 choices
.add ("Two Value Vertical");
198 choices
.add ("Three Value Horizontal");
199 choices
.add ("Three Value Vertical");
202 void setIndex (int newIndex
)
204 const Slider::SliderStyle types
[] = { Slider::LinearHorizontal
,
205 Slider::LinearVertical
,
208 Slider::RotaryHorizontalDrag
,
209 Slider::RotaryVerticalDrag
,
210 Slider::IncDecButtons
,
211 Slider::TwoValueHorizontal
,
212 Slider::TwoValueVertical
,
213 Slider::ThreeValueHorizontal
,
214 Slider::ThreeValueVertical
};
216 if (newIndex
>= 0 && newIndex
< numElementsInArray (types
))
218 document
.perform (new SliderTypeChangeAction (component
, *document
.getComponentLayout(), types
[newIndex
]),
219 "Change Slider style");
225 const Slider::SliderStyle types
[] = { Slider::LinearHorizontal
,
226 Slider::LinearVertical
,
229 Slider::RotaryHorizontalDrag
,
230 Slider::RotaryVerticalDrag
,
231 Slider::IncDecButtons
,
232 Slider::TwoValueHorizontal
,
233 Slider::TwoValueVertical
,
234 Slider::ThreeValueHorizontal
,
235 Slider::ThreeValueVertical
};
237 for (int i
= 0; i
< numElementsInArray (types
); ++i
)
238 if (types
[i
] == dynamic_cast <Slider
*> (component
)->getSliderStyle())
245 class SliderTypeChangeAction
: public ComponentUndoableAction
<Slider
>
248 SliderTypeChangeAction (Slider
* const comp
, ComponentLayout
& layout
, const Slider::SliderStyle newState_
)
249 : ComponentUndoableAction
<Slider
> (comp
, layout
),
252 oldState
= comp
->getSliderStyle();
258 getComponent()->setSliderStyle (newState
);
266 getComponent()->setSliderStyle (oldState
);
271 Slider::SliderStyle newState
, oldState
;
275 //==============================================================================
276 class SliderTextboxProperty
: public ComponentChoiceProperty
<Slider
>
279 SliderTextboxProperty (Slider
* slider
, JucerDocument
& document
)
280 : ComponentChoiceProperty
<Slider
> ("text position", slider
, document
)
282 choices
.add ("No text box");
283 choices
.add ("Text box on left");
284 choices
.add ("Text box on right");
285 choices
.add ("Text box above");
286 choices
.add ("Text box below");
289 void setIndex (int newIndex
)
291 const Slider::TextEntryBoxPosition types
[] = { Slider::NoTextBox
,
293 Slider::TextBoxRight
,
294 Slider::TextBoxAbove
,
295 Slider::TextBoxBelow
};
297 if (newIndex
>= 0 && newIndex
< numElementsInArray (types
))
299 document
.perform (new SliderTextBoxChangeAction (component
, *document
.getComponentLayout(), types
[newIndex
]),
300 "Change Slider textbox");
306 const Slider::TextEntryBoxPosition types
[] = { Slider::NoTextBox
,
308 Slider::TextBoxRight
,
309 Slider::TextBoxAbove
,
310 Slider::TextBoxBelow
};
312 for (int i
= 0; i
< numElementsInArray (types
); ++i
)
313 if (types
[i
] == component
->getTextBoxPosition())
320 class SliderTextBoxChangeAction
: public ComponentUndoableAction
<Slider
>
323 SliderTextBoxChangeAction (Slider
* const comp
, ComponentLayout
& layout
, const Slider::TextEntryBoxPosition newState_
)
324 : ComponentUndoableAction
<Slider
> (comp
, layout
),
327 oldState
= comp
->getTextBoxPosition();
333 getComponent()->setTextBoxStyle (newState
,
334 ! getComponent()->isTextBoxEditable(),
335 getComponent()->getTextBoxWidth(),
336 getComponent()->getTextBoxHeight());
344 getComponent()->setTextBoxStyle (oldState
,
345 ! getComponent()->isTextBoxEditable(),
346 getComponent()->getTextBoxWidth(),
347 getComponent()->getTextBoxHeight());
352 Slider::TextEntryBoxPosition newState
, oldState
;
356 //==============================================================================
357 class SliderTextboxEditableProperty
: public ComponentBooleanProperty
<Slider
>
360 SliderTextboxEditableProperty (Slider
* slider
, JucerDocument
& document
)
361 : ComponentBooleanProperty
<Slider
> ("text box mode", "Editable", "Editable", slider
, document
)
365 void setState (bool newState
)
367 document
.perform (new SliderEditableChangeAction (component
, *document
.getComponentLayout(), newState
),
368 "Change Slider editability");
371 bool getState() const
373 return component
->isTextBoxEditable();
377 class SliderEditableChangeAction
: public ComponentUndoableAction
<Slider
>
380 SliderEditableChangeAction (Slider
* const comp
, ComponentLayout
& layout
, const bool newState_
)
381 : ComponentUndoableAction
<Slider
> (comp
, layout
),
384 oldState
= comp
->isTextBoxEditable();
390 getComponent()->setTextBoxIsEditable (newState
);
398 getComponent()->setTextBoxIsEditable (oldState
);
403 bool newState
, oldState
;
407 //==============================================================================
408 class SliderTextboxSizeProperty
: public ComponentTextProperty
<Slider
>
411 SliderTextboxSizeProperty (Slider
* slider
, JucerDocument
& document
, const bool isWidth_
)
412 : ComponentTextProperty
<Slider
> (isWidth_
? "text box width" : "text box height",
413 12, false, slider
, document
),
418 void setText (const String
& newText
)
420 document
.perform (new SliderBoxSizeChangeAction (component
, *document
.getComponentLayout(), isWidth
, newText
.getIntValue()),
421 "Change Slider textbox size");
424 const String
getText() const
426 return String (isWidth
? component
->getTextBoxWidth()
427 : component
->getTextBoxHeight());
433 class SliderBoxSizeChangeAction
: public ComponentUndoableAction
<Slider
>
436 SliderBoxSizeChangeAction (Slider
* const comp
, ComponentLayout
& layout
, const bool isWidth_
, int newSize_
)
437 : ComponentUndoableAction
<Slider
> (comp
, layout
),
441 oldSize
= isWidth
? comp
->getTextBoxWidth()
442 : comp
->getTextBoxHeight();
450 getComponent()->setTextBoxStyle (getComponent()->getTextBoxPosition(),
451 ! getComponent()->isTextBoxEditable(),
453 getComponent()->getTextBoxHeight());
455 getComponent()->setTextBoxStyle (getComponent()->getTextBoxPosition(),
456 ! getComponent()->isTextBoxEditable(),
457 getComponent()->getTextBoxWidth(),
468 getComponent()->setTextBoxStyle (getComponent()->getTextBoxPosition(),
469 ! getComponent()->isTextBoxEditable(),
471 getComponent()->getTextBoxHeight());
473 getComponent()->setTextBoxStyle (getComponent()->getTextBoxPosition(),
474 ! getComponent()->isTextBoxEditable(),
475 getComponent()->getTextBoxWidth(),
482 int newSize
, oldSize
;
486 //==============================================================================
487 class SliderRangeProperty
: public ComponentTextProperty
<Slider
>
490 SliderRangeProperty (Slider
* slider
, JucerDocument
& document
,
491 const String
& name
, const int rangeParam_
)
492 : ComponentTextProperty
<Slider
> (name
, 15, false, slider
, document
),
493 rangeParam (rangeParam_
)
497 void setText (const String
& newText
)
500 state
[0] = component
->getMinimum();
501 state
[1] = component
->getMaximum();
502 state
[2] = component
->getInterval();
504 state
[rangeParam
] = newText
.getDoubleValue();
506 document
.perform (new SliderRangeChangeAction (component
, *document
.getComponentLayout(), state
),
507 "Change Slider range");
510 const String
getText() const
512 Slider
* s
= dynamic_cast <Slider
*> (component
);
518 return String (s
->getMinimum());
521 return String (s
->getMaximum());
524 return String (s
->getInterval());
531 return String::empty
;
535 const int rangeParam
;
537 class SliderRangeChangeAction
: public ComponentUndoableAction
<Slider
>
540 SliderRangeChangeAction (Slider
* const comp
, ComponentLayout
& layout
, const double newState_
[3])
541 : ComponentUndoableAction
<Slider
> (comp
, layout
)
543 newState
[0] = newState_
[0];
544 newState
[1] = newState_
[1];
545 newState
[2] = newState_
[2];
547 oldState
[0] = comp
->getMinimum();
548 oldState
[1] = comp
->getMaximum();
549 oldState
[2] = comp
->getInterval();
555 getComponent()->setRange (newState
[0], newState
[1], newState
[2]);
563 getComponent()->setRange (oldState
[0], oldState
[1], oldState
[2]);
568 double newState
[3], oldState
[3];
572 //==============================================================================
573 class SliderSkewProperty
: public ComponentTextProperty
<Slider
>
576 SliderSkewProperty (Slider
* slider
, JucerDocument
& document
)
577 : ComponentTextProperty
<Slider
> ("skew factor", 12, false, slider
, document
)
581 void setText (const String
& newText
)
583 const double skew
= jlimit (0.001, 1000.0, newText
.getDoubleValue());
585 document
.perform (new SliderSkewChangeAction (component
, *document
.getComponentLayout(), skew
),
586 "Change Slider skew");
589 const String
getText() const
591 Slider
* s
= dynamic_cast <Slider
*> (component
);
594 return String (s
->getSkewFactor());
598 class SliderSkewChangeAction
: public ComponentUndoableAction
<Slider
>
601 SliderSkewChangeAction (Slider
* const comp
, ComponentLayout
& layout
, const double newValue_
)
602 : ComponentUndoableAction
<Slider
> (comp
, layout
)
604 newValue
= newValue_
;
605 oldValue
= comp
->getSkewFactor();
611 getComponent()->setSkewFactor (newValue
);
619 getComponent()->setSkewFactor (oldValue
);
624 double newValue
, oldValue
;
628 //==============================================================================
629 static const String
sliderStyleToString (Slider::SliderStyle style
)
633 case Slider::LinearHorizontal
:
634 return "LinearHorizontal";
635 case Slider::LinearVertical
:
636 return "LinearVertical";
637 case Slider::LinearBar
:
641 case Slider::RotaryHorizontalDrag
:
642 return "RotaryHorizontalDrag";
643 case Slider::RotaryVerticalDrag
:
644 return "RotaryVerticalDrag";
645 case Slider::IncDecButtons
:
646 return "IncDecButtons";
647 case Slider::TwoValueHorizontal
:
648 return "TwoValueHorizontal";
649 case Slider::TwoValueVertical
:
650 return "TwoValueVertical";
651 case Slider::ThreeValueHorizontal
:
652 return "ThreeValueHorizontal";
653 case Slider::ThreeValueVertical
:
654 return "ThreeValueVertical";
661 return String::empty
;
664 static Slider::SliderStyle
sliderStringToStyle (const String
& s
)
666 if (s
== "LinearHorizontal")
667 return Slider::LinearHorizontal
;
668 else if (s
== "LinearVertical")
669 return Slider::LinearVertical
;
670 else if (s
== "LinearBar")
671 return Slider::LinearBar
;
672 else if (s
== "Rotary")
673 return Slider::Rotary
;
674 else if (s
== "RotaryHorizontalDrag")
675 return Slider::RotaryHorizontalDrag
;
676 else if (s
== "RotaryVerticalDrag")
677 return Slider::RotaryVerticalDrag
;
678 else if (s
== "IncDecButtons")
679 return Slider::IncDecButtons
;
680 else if (s
.startsWithIgnoreCase ("TwoValueHoriz"))
681 return Slider::TwoValueHorizontal
;
682 else if (s
.startsWithIgnoreCase ("TwoValueVert"))
683 return Slider::TwoValueVertical
;
684 else if (s
.startsWithIgnoreCase ("ThreeValueHoriz"))
685 return Slider::ThreeValueHorizontal
;
686 else if (s
.startsWithIgnoreCase ("ThreeValueVert"))
687 return Slider::ThreeValueVertical
;
690 return Slider::LinearHorizontal
;
693 static const String
textBoxPosToString (const Slider::TextEntryBoxPosition pos
)
697 case Slider::NoTextBox
:
699 case Slider::TextBoxLeft
:
700 return "TextBoxLeft";
701 case Slider::TextBoxRight
:
702 return "TextBoxRight";
703 case Slider::TextBoxAbove
:
704 return "TextBoxAbove";
705 case Slider::TextBoxBelow
:
706 return "TextBoxBelow";
712 return String::empty
;
715 static const Slider::TextEntryBoxPosition
stringToTextBoxPos (const String
& s
)
717 if (s
== "NoTextBox")
718 return Slider::NoTextBox
;
719 else if (s
== "TextBoxLeft")
720 return Slider::TextBoxLeft
;
721 else if (s
== "TextBoxRight")
722 return Slider::TextBoxRight
;
723 else if (s
== "TextBoxAbove")
724 return Slider::TextBoxAbove
;
725 else if (s
== "TextBoxBelow")
726 return Slider::TextBoxBelow
;
729 return Slider::TextBoxLeft
;
734 #endif // __JUCER_SLIDERHANDLER_JUCEHEADER__